package com.baitiaojun.web.core.filter;

import com.baitiaojun.common.enums.impl.HttpMethodEnums;
import com.baitiaojun.common.utils.string.StringUtils;
import com.baitiaojun.web.config.WebCacheProperties;
import org.springframework.http.MediaType;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 在过滤器中增加HttpServletRequest, 后续可重复读取json请求参数
 */
public class ServletRequestCacheFilter extends OncePerRequestFilter {

    private final WebCacheProperties webCacheProperties;

    public ServletRequestCacheFilter(WebCacheProperties webCacheProperties) {
        this.webCacheProperties = webCacheProperties;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ServletRequestCacheWrapper repeatServletRequestWrapper = null;
        //判断是否是application/json类型的请求参数
        if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
            repeatServletRequestWrapper = new ServletRequestCacheWrapper(request, response); //创建可重复读取请求json参数对象
        }
        if (repeatServletRequestWrapper == null) {
            filterChain.doFilter(request, response);
        } else {
            filterChain.doFilter(repeatServletRequestWrapper, response);
        }
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        List<String> excludesUrl = webCacheProperties.getExcludesUrl();
        String requestURI = request.getRequestURI();
        requestURI = requestURI.replace(request.getContextPath(), "");
        String method = request.getMethod();
        if (method == null || method.equals(HttpMethodEnums.GET.getName()) || method.equals(HttpMethodEnums.DELETE.getName())) {
            return false;
        }
        return StringUtils.matchAll(excludesUrl, requestURI);
    }
}
